﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;

namespace XYAC.Framework.WatchDog
{

    public static class SingleInstanceChecker
    {
        private const string EventName = "Global\\XYAC_Framework_WatchDog_SingleInstance_Event";

        [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        private static extern IntPtr CreateEvent(
            IntPtr lpEventAttributes,
            bool bManualReset,
            bool bInitialState,
            string lpName);

        [DllImport("kernel32.dll", SetLastError = true)]
        private static extern bool CloseHandle(IntPtr hObject);

        private static IntPtr _eventHandle = IntPtr.Zero;

        /// <summary>
        /// 检查当前进程是否为单例。
        /// </summary>
        /// <returns>如果已有实例运行，返回 true；否则，返回 false。</returns>
        public static bool IsAlreadyRunning()
        {
            // 尝试创建一个命名事件
            _eventHandle = CreateEvent(IntPtr.Zero, true, true, EventName);

            if (_eventHandle == IntPtr.Zero)
            {
                // 创建事件失败，抛出异常
                throw new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error(), "无法创建事件对象。");
            }

            // 如果 GetLastError 返回 ERROR_ALREADY_EXISTS，表示事件已经存在，已有实例在运行
            int lastError = Marshal.GetLastWin32Error();
            const int ERROR_ALREADY_EXISTS = 183;

            return lastError == ERROR_ALREADY_EXISTS;
        }

        /// <summary>
        /// 释放事件句柄。
        /// </summary>
        public static void Release()
        {
            if (_eventHandle != IntPtr.Zero)
            {
                CloseHandle(_eventHandle);
                _eventHandle = IntPtr.Zero;
            }
        }
    }
}